#ifndef _NTH_LIB_h
#include <nth-lib.h>
#endif

#ifndef _STDIO_H
#include <stdio.h>
#endif

#ifndef _STDLIB_H
#include <stdlib.h>
#endif

#ifndef _STRING_H
#include <string.h>
#endif

/* do not alphabetize main */

int main(int argc, char * argv[]){

	int error = 0;

	struct Nth_Variable results_dir;

	struct Nth_Program * program = 0;
	struct Nth_Number result;

	error = Create_Nth_Program(&program);

	if (error){
		return 1;
	}

	result.number_buffer = 0;
	result.number_length = 0;

	program->argc = argc;
	program->argv = argv;
	program->arg_index = 1;

	results_dir.variable_name = "results-dir";
	results_dir.variable_value = ".nth";

	error = Set_Nth_Variable(
		program,
		&results_dir
	);

	error = Link_Nth_Plugins(program);

	if (error){

		Print_Nth_Failures(program);
		Clean_Nth_Number(&result);
		Destroy_Nth_Program(&program);

		return 1;
	}

	error = Evaluate_Nth_Expression(
		program,
		&result
	);

	if (error){

		Print_Nth_Failures(program);
		Clean_Nth_Number(&result);
		Unlink_Nth_Plugins(program);
		Destroy_Nth_Program(&program);

		return 1;
	}

	if (result.number_length > 0){

		error = Read_Nth_Stack_Index(program);

		if (error){

			Push_Nth_Failure(
				program,
				"main",
				"Failed to get stack index"
			);

			Print_Nth_Failures(program);
			Destroy_Nth_Program(&program);

			return 1;
		}

		error = Export_Nth_Results(
			program,
			&result,
			1
		);

		if (error){

			Push_Nth_Failure(
				program,
				"main",
				"Failed to export results"
			);

			Print_Nth_Failures(program);
			Clean_Nth_Number(&result);
			Unlink_Nth_Plugins(program);
			Destroy_Nth_Program(&program);

			return 1;
		}

		program->stack_index++;

		error = Write_Nth_Stack_Index(program);

		if (error){

			Push_Nth_Failure(
				program,
				"main",
				"Failed to write new stack index"
			);

			Print_Nth_Failures(program);
			Clean_Nth_Number(&result);
			Unlink_Nth_Plugins(program);
			Destroy_Nth_Program(&program);

			return 1;
		}

	}

	Clean_Nth_Number(&result);
	Unlink_Nth_Plugins(program);
	Destroy_Nth_Program(&program);
	return 0;
}

